package com.eduagent.xwqeduagent.api.RecordingFileTranscription.service;

import com.eduagent.xwqeduagent.api.RecordingFileTranscription.constant.FileTranscriptionConstant;
import com.eduagent.xwqeduagent.api.RecordingFileTranscription.model.ResultQueryResponse;
import com.eduagent.xwqeduagent.api.RecordingFileTranscription.model.UploadResponse;
import com.eduagent.xwqeduagent.api.RecordingFileTranscription.util.SignatureUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.concurrent.TimeUnit;

/**
 * 录音文件转写服务
 */
@Service
@Slf4j
public class FileTranscriptionService {

    private final RestTemplate restTemplate = new RestTemplate();
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    /**
     * 上传录音文件
     * 
     * @param file 录音文件
     * @param duration 录音时长（毫秒）
     * @param language 语种
     * @param pd 领域
     * @param hotWord 热词，用以提升专业词汇的识别率，格式：热词1|热词2|热词3
     * @param candidate 多候选开关，0：关闭(默认)，1：打开
     * @param roleType 是否开启角色分离，0：不开启(默认)，1：通用角色分离
     * @param roleNum 说话人数，取值范围0-10，默认为0进行盲分
     * @param languageType 语言识别模式选择，1：自动中英文模式(默认)，2:中文模式，4:纯中文模式
     * @return 上传响应
     * @throws Exception 上传过程中的异常
     */
    public UploadResponse uploadFile(MultipartFile file, Long duration, String language, String pd,
                                    String hotWord, Short candidate, Short roleType, Short roleNum, 
                                    Integer languageType) throws Exception {
        // 准备请求参数
        long ts = System.currentTimeMillis() / 1000;
        String signa = SignatureUtil.generateSignature(ts);

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(FileTranscriptionConstant.UPLOAD_URL)
                .queryParam("duration", duration)
                .queryParam("signa", signa)
                .queryParam("fileName", encodeFileName(file.getOriginalFilename()))
                .queryParam("fileSize", file.getSize())
                .queryParam("appId", FileTranscriptionConstant.APP_ID)
                .queryParam("ts", ts)
                .queryParam("sysDicts", "uncivilizedLanguage");
        
        // 添加可选参数
        if (language != null && !language.isEmpty()) {
            builder.queryParam("language", language);
        }
        
        if (pd != null && !pd.isEmpty()) {
            builder.queryParam("pd", pd);
        }
        
        // 添加新增的可选参数
        if (hotWord != null && !hotWord.isEmpty()) {
            builder.queryParam("hotWord", hotWord);
        }
        
        if (candidate != null) {
            builder.queryParam("candidate", candidate);
        }
        
        if (roleType != null) {
            builder.queryParam("roleType", roleType);
            
            // 只有当roleType为1时，roleNum才有意义
            if (roleType == 1 && roleNum != null) {
                builder.queryParam("roleNum", roleNum);
            }
        }
        
        if (languageType != null) {
            builder.queryParam("languageType", languageType);
        }
        
        // 构建请求头 - 严格按照文档要求
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.set("Chunked", "false");
        
        // 构建请求体
        HttpEntity<byte[]> requestEntity = new HttpEntity<>(file.getBytes(), headers);
        
        // 记录请求URL和参数
        String requestUrl = builder.build().toUriString();
        log.info("讯飞转写请求URL: {}", requestUrl);
        
        // 发送请求
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(
                requestUrl,
                requestEntity,
                String.class
        );
        
        // 记录响应内容
        String responseBody = responseEntity.getBody();
        log.info("讯飞转写响应: {}", responseBody);
        
        // 解析响应
        return objectMapper.readValue(responseBody, UploadResponse.class);
    }
    
    /**
     * 上传录音文件URL
     * 
     * @param audioUrl 录音文件URL
     * @param fileName 文件名
     * @param duration 录音时长（毫秒）
     * @param language 语种
     * @param pd 领域
     * @param hotWord 热词，用以提升专业词汇的识别率，格式：热词1|热词2|热词3
     * @param candidate 多候选开关，0：关闭(默认)，1：打开
     * @param roleType 是否开启角色分离，0：不开启(默认)，1：通用角色分离
     * @param roleNum 说话人数，取值范围0-10，默认为0进行盲分
     * @param languageType 语言识别模式选择，1：自动中英文模式(默认)，2:中文模式，4:纯中文模式
     * @return 上传响应
     * @throws Exception 上传过程中的异常
     */
    public UploadResponse uploadFileUrl(String audioUrl, String fileName, Long duration, String language, String pd,
                                       String hotWord, Short candidate, Short roleType, Short roleNum, 
                                       Integer languageType) throws Exception {
        // 准备请求参数
        long ts = System.currentTimeMillis() / 1000;
        String signa = SignatureUtil.generateSignature(ts);
        
        // 构建URL - 按照示例的参数顺序
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(FileTranscriptionConstant.UPLOAD_URL)
                .queryParam("duration", duration)
                .queryParam("signa", signa)
                .queryParam("fileName", encodeFileName(fileName))
                .queryParam("fileSize", 10000) // URL模式可以随意填写文件大小
                .queryParam("appId", FileTranscriptionConstant.APP_ID)
                .queryParam("ts", ts)
                .queryParam("audioMode", "urlLink")
                .queryParam("audioUrl", audioUrl)
                .queryParam("sysDicts", "uncivilizedLanguage");
                
        // 添加可选参数
        if (language != null && !language.isEmpty()) {
            builder.queryParam("language", language);
        }
        
        if (pd != null && !pd.isEmpty()) {
            builder.queryParam("pd", pd);
        }
        
        // 添加新增的可选参数
        if (hotWord != null && !hotWord.isEmpty()) {
            builder.queryParam("hotWord", hotWord);
        }
        
        if (candidate != null) {
            builder.queryParam("candidate", candidate);
        }
        
        if (roleType != null) {
            builder.queryParam("roleType", roleType);
            
            // 只有当roleType为1时，roleNum才有意义
            if (roleType == 1 && roleNum != null) {
                builder.queryParam("roleNum", roleNum);
            }
        }
        
        if (languageType != null) {
            builder.queryParam("languageType", languageType);
        }
        
        // 记录请求URL
        String requestUrl = builder.build().toUriString();
        log.info("讯飞转写URL请求: {}", requestUrl);
        
        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        
        // 构建空请求体
        HttpEntity<String> requestEntity = new HttpEntity<>("{}", headers);
        
        // 发送请求
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(
                requestUrl,
                requestEntity,
                String.class
        );
        
        // 记录响应
        String responseBody = responseEntity.getBody();
        log.info("讯飞转写响应: {}", responseBody);
        
        // 解析响应
        return objectMapper.readValue(responseBody, UploadResponse.class);
    }
    
    /**
     * 查询转写结果
     * 
     * @param orderId 订单ID
     * @return 查询响应
     * @throws Exception 查询过程中的异常
     */
    public ResultQueryResponse queryResult(String orderId) throws Exception {
        // 准备请求参数
        long ts = System.currentTimeMillis() / 1000;
        String signa = SignatureUtil.generateSignature(ts);
        
        // 构建URL
        String url = UriComponentsBuilder.fromHttpUrl(FileTranscriptionConstant.GET_RESULT_URL)
                .queryParam("appId", FileTranscriptionConstant.APP_ID)
                .queryParam("signa", signa)
                .queryParam("ts", ts)
                .queryParam("orderId", orderId)
                .build()
                .toUriString();
        
        // 发送请求
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        
        // 解析响应
        return objectMapper.readValue(responseEntity.getBody(), ResultQueryResponse.class);
    }
    
    /**
     * 查询转写结果（带轮询）
     * 
     * @param orderId 订单ID
     * @param maxRetries 最大重试次数
     * @param intervalSeconds 轮询间隔（秒）
     * @return 查询响应
     * @throws Exception 查询过程中的异常
     */
    public ResultQueryResponse queryResultWithPolling(String orderId, int maxRetries, int intervalSeconds) throws Exception {
        ResultQueryResponse response = null;
        int retries = 0;
        
        while (retries < maxRetries) {
            response = queryResult(orderId);
            
            // 如果已完成或失败，直接返回
            if (response.isCompleted() || response.isFailed()) {
                return response;
            }
            
            // 等待一段时间再查询
            log.info("订单 {} 处理中，等待 {} 秒后再次查询，当前重试次数: {}/{}", 
                    orderId, intervalSeconds, retries + 1, maxRetries);
            TimeUnit.SECONDS.sleep(intervalSeconds);
            
            // 增加重试次数
            retries++;
        }
        
        return response;
    }
    
    /**
     * 编码文件名（处理中文文件名）
     * 
     * @param fileName 原始文件名
     * @return 编码后的文件名
     */
    private String encodeFileName(String fileName) {
        if (fileName == null) {
            return "audio.mp3";
        }
        try {
            return java.net.URLEncoder.encode(fileName, "UTF-8");
        } catch (Exception e) {
            return fileName;
        }
    }
} 